<script lang="ts">
import {defineComponent, reactive} from "vue"
import type {PropType} from 'vue';
import {useDisabledStatus} from "@/hooks/form";

/**
 * 标签表单组件
 */
export default defineComponent({
  name: "TagsInput",
  emits: ['update:modelValue', 'change', 'input'],
  props: {
    modelValue: {
      type: Array as PropType<string[]>,
      required: true
    },
    limit: {
      type: Number,
      default: 15
    },
    maxlength: {
      type: Number,
      default: 20
    },
    disabled: {
      type: Boolean
    }
  },
  setup(props, {emit}) {
    const IsDisabled = useDisabledStatus(props.disabled)

    //新增标签
    const add = reactive({show: false, value: ''})

    //编辑标签
    const edit: { show: number | false, value: string } = reactive({show: false, value: ''})

    /**
     * 打开新增标签
     */
    function openAdd() {
      add.show = true
      add.value = ''
    }

    /**
     * 打开标签编辑
     * @param index
     * @param value
     */
    function openEdit(index: number, value: string) {
      if (!IsDisabled.value) {
        edit.show = index
        edit.value = value
      }
    }

    /**
     * 更改数据
     * @param value
     * @constructor
     */
    function ValueChange(value: Array<string>) {
      emit('change', value)
      emit('input', value)
      emit('update:modelValue', value)
    }

    /**
     * 移除标签
     * @param index
     */
    function closeTags(index: number) {
      let value = [...props.modelValue]
      value.splice(index, 1)
      ValueChange(value)
    }


    /**
     * 编辑标签页
     * @param event
     */
    function editInputBlur(event: any) {
      if (edit.show === false) return
      const {value}: { value: string } = event.target
      let tags = []
      for (let index in props.modelValue) {
        let sort = parseInt(index)
        let val = props.modelValue[index]
        if (sort === edit.show) {
          if (value.length > 0 && tags.indexOf(value) === -1) {
            tags.push(value)
          }
        } else if (tags.indexOf(val) === -1) {
          tags.push(val)
        }
      }
      ValueChange(tags)
      edit.show = false
      edit.value = ''
    }


    /**
     * 新增标签页
     * @param event
     */
    function addInputBlur(event: any) {
      if (add.show === false) return
      const {value}: { value: string } = event.target
      if (value.length === 0) {
        add.show = false
      } else {
        let _value: string[] = [...props.modelValue]
        _value.push(value)
        ValueChange(_value)
        add.show = false
        add.value = ''
      }
    }


    function InputAutoFocus(event) {
      if (event && event.is_focus !== 1) {
        event.focus()
        event.is_focus = 1
      }
    }


    return {
      IsDisabled,
      closeTags,
      openAdd,
      openEdit,
      add,
      edit,
      addInputBlur,
      editInputBlur,
      InputAutoFocus
    }
  }
})
</script>

<template>
  <div class="tags-input">
    <el-tag v-for="(item,index) in modelValue" :key="index" :class="{'tag-input':index===edit.show}" :closable="index!==edit.show && !IsDisabled" @close="closeTags(index)" @click="openEdit(index,item)" type="primary">
      <template v-if="index===edit.show">
        <el-input size="small" :disabled="IsDisabled" :ref="InputAutoFocus" v-model.trim="edit.value" :maxlength show-word-limit @keyup.enter="editInputBlur" @blur="editInputBlur"></el-input>
      </template>
      <template v-else>{{ item }}</template>
    </el-tag>
    <el-tag v-if="add.show" type="info" class="tag-input">
      <el-input size="small" :disabled="IsDisabled" :ref="InputAutoFocus" v-model.trim="add.value" :maxlength show-word-limit @keyup.enter="addInputBlur" @blur="addInputBlur"></el-input>
    </el-tag>
    <el-tag v-else-if="limit>modelValue.length && edit.show===false && !IsDisabled" type="primary" @click="openAdd">
      <app-icon name="plus"></app-icon>
    </el-tag>
  </div>
</template>
<style lang="scss" scoped>
.tags-input {
  .el-tag {
    cursor: pointer;
    margin-right: 5px;
    margin-bottom: 5px;

    &.tag-input {
      padding: 0;

      .el-input {
        max-width: 130px;
      }
    }
  }
}
</style>
